package pixelradar.gui;

import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Gui;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.util.math.MathHelper;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import org.lwjgl.input.Mouse;

@SideOnly(Side.CLIENT)
public abstract class MwGuiSlot {
    public final int scrollBarWidth = 6;
    protected final Minecraft mc;
    public int width;
    public int height;
    public int top;
    public int bottom;
    public int right;
    public int left;
    public int headerPadding;
    protected int mouseX;
    protected int mouseY;
    protected boolean centerListVertically = true;
    protected float initialClickY = -2.0F;
    protected float scrollMultiplier;
    protected float amountScrolled;
    protected int selectedElement = -1;
    protected long lastClicked;
    protected boolean showSelectionBox = true;
    protected boolean hasListHeader;
    int spacingY = 4;
    private int scrollUpButtonID;
    private int scrollDownButtonID;
    private boolean enabled = false;

    public MwGuiSlot(Minecraft mcIn, int width, int height, int topIn, int bottomIn, int left) {
        this.mc = mcIn;
        this.width = width;
        this.height = height;
        this.top = topIn;
        this.bottom = bottomIn;
        this.left = left;
        this.right = left + width;
    }

    public void setDimensions(int widthIn, int heightIn, int topIn, int bottomIn, int left) {
        this.width = widthIn;
        this.height = heightIn;
        this.top = topIn;
        this.bottom = bottomIn;
        this.left = left;
        this.right = left + widthIn;
    }

    public void setShowSelectionBox(boolean showSelectionBoxIn) {
        this.showSelectionBox = showSelectionBoxIn;
    }

    protected void setHasListHeader(boolean hasListHeaderIn, int headerPaddingIn) {
        this.hasListHeader = hasListHeaderIn;
        this.headerPadding = headerPaddingIn;
        if (!hasListHeaderIn) {
            this.headerPadding = 0;
        }

    }

    protected abstract int getSize();

    protected abstract void elementClicked(int var1, boolean var2, int var3, int var4, int var5);

    protected abstract boolean isSelected(int var1);

    protected abstract int getSlotHeight(int var1);

    protected int getContentHeight() {
        int slotHeight = this.headerPadding;

        for (int index = 0; index < this.getSize(); ++index) {
            slotHeight += this.getSlotHeight(index);
        }

        return slotHeight;
    }

    protected abstract void drawBackground();

    protected void slotOutOfBounds(int index, int p_178040_2_, int p_178040_3_) {
    }

    protected abstract void drawSlot(int var1, int var2, int var3, int var4, int var5, int var6);

    protected void drawListHeader(int x, int y, Tessellator tess) {
    }

    protected void clickedHeader(int p_148132_1_, int p_148132_2_) {
    }

    protected void renderDecorations(int p_148142_1_, int p_148142_2_) {
    }

    public int getSlotIndexFromScreenCoords(int x, int y) {
        int k = this.left + (this.width / 2 - this.getListWidth() / 2);
        this.getClass();
        int l = this.left + this.width / 2 + this.getListWidth() / 2 - 6;
        int i1 = y - this.top - this.headerPadding + (int) this.amountScrolled;
        int yStart = 0;
        int yStop = yStart + this.getSlotHeight(0);

        for (int index = 0; index < this.getSize(); ++index) {
            if (i1 >= yStart && i1 <= yStop) {
                return x < this.getScrollBarX() && x >= k && x <= l && i1 >= 0 ? index : -1;
            }

            yStart = yStop;
            yStop += this.getSlotHeight(index + 1);
        }

        return -1;
    }

    public void registerScrollButtons(int scrollUpButtonIDIn, int scrollDownButtonIDIn) {
        this.scrollUpButtonID = scrollUpButtonIDIn;
        this.scrollDownButtonID = scrollDownButtonIDIn;
    }

    protected void bindAmountScrolled() {
        int i = this.getMaxScroll();
        if (i < 0) {
            i /= 2;
        }

        if (!this.centerListVertically && i < 0) {
            i = 0;
        }

        this.amountScrolled = MathHelper.clamp(this.amountScrolled, 0.0F, (float) i);
    }

    public int getMaxScroll() {
        return Math.max(0, this.getContentHeight() - (this.bottom - this.top));
    }

    public int getAmountScrolled() {
        return (int) this.amountScrolled;
    }

    public boolean isMouseYWithinSlotBounds() {
        return this.mouseY >= this.top && this.mouseY <= this.bottom;
    }

    public boolean isMouseXWithinSlotBounds() {
        return this.mouseX >= this.left && this.mouseX <= this.right;
    }

    public boolean isMouseInField() {
        return this.isMouseYWithinSlotBounds() && this.isMouseXWithinSlotBounds();
    }

    public void scrollBy(int amount) {
        this.amountScrolled += (float) amount;
        this.bindAmountScrolled();
        this.initialClickY = -2.0F;
    }

    public void actionPerformed(GuiButton button) {
        if (button.enabled) {
            int slotHeight = this.getAverageSlotHeight();
            if (button.id == this.scrollUpButtonID) {
                this.amountScrolled -= (float) (slotHeight * 2 / 3);
                this.initialClickY = -2.0F;
                this.bindAmountScrolled();
            } else if (button.id == this.scrollDownButtonID) {
                this.amountScrolled += (float) (slotHeight * 2 / 3);
                this.initialClickY = -2.0F;
                this.bindAmountScrolled();
            }
        }

    }

    public void drawScreen(int mouseXIn, int mouseYIn, float f) {
        if (this.getEnabled()) {
            this.mouseX = mouseXIn;
            this.mouseY = mouseYIn;
            this.drawBackground();
            int k = this.getScrollBarX();
            this.getClass();
            int l = k + 6;
            this.bindAmountScrolled();
            GlStateManager.disableLighting();
            GlStateManager.disableFog();
            Tessellator tessellator = Tessellator.getInstance();
            BufferBuilder vertexbuffer = tessellator.getBuffer();
            this.drawContainerBackground(tessellator);
            int i1 = this.left + (this.width / 2 - this.getListWidth() / 2);
            int j1 = this.top - (int) this.amountScrolled;
            if (this.hasListHeader) {
                this.drawListHeader(i1, j1, tessellator);
            }

            this.drawSelectionBox(i1, j1, mouseXIn, mouseYIn);
            GlStateManager.disableDepth();
            GlStateManager.enableBlend();
            GlStateManager.tryBlendFuncSeparate(770, 771, 0, 1);
            GlStateManager.disableAlpha();
            GlStateManager.shadeModel(7425);
            GlStateManager.disableTexture2D();
            int k1 = this.getMaxScroll();
            if (k1 > 0) {
                int l1 = (this.bottom - this.top) * (this.bottom - this.top) / this.getContentHeight();
                l1 = MathHelper.clamp(l1, 32, this.bottom - this.top - 8);
                int i2 = (int) this.amountScrolled * (this.bottom - this.top - l1) / k1 + this.top;
                if (i2 < this.top) {
                    i2 = this.top;
                }

                vertexbuffer.begin(7, DefaultVertexFormats.POSITION_TEX_COLOR);
                vertexbuffer.pos((double) k, (double) this.bottom, 0.0D).tex(0.0D, 1.0D).color(0, 0, 0, 255).endVertex();
                vertexbuffer.pos((double) l, (double) this.bottom, 0.0D).tex(1.0D, 1.0D).color(0, 0, 0, 255).endVertex();
                vertexbuffer.pos((double) l, (double) this.top, 0.0D).tex(1.0D, 0.0D).color(0, 0, 0, 255).endVertex();
                vertexbuffer.pos((double) k, (double) this.top, 0.0D).tex(0.0D, 0.0D).color(0, 0, 0, 255).endVertex();
                tessellator.draw();
                vertexbuffer.begin(7, DefaultVertexFormats.POSITION_TEX_COLOR);
                vertexbuffer.pos((double) k, (double) (i2 + l1), 0.0D).tex(0.0D, 1.0D).color(128, 128, 128, 255).endVertex();
                vertexbuffer.pos((double) l, (double) (i2 + l1), 0.0D).tex(1.0D, 1.0D).color(128, 128, 128, 255).endVertex();
                vertexbuffer.pos((double) l, (double) i2, 0.0D).tex(1.0D, 0.0D).color(128, 128, 128, 255).endVertex();
                vertexbuffer.pos((double) k, (double) i2, 0.0D).tex(0.0D, 0.0D).color(128, 128, 128, 255).endVertex();
                tessellator.draw();
                vertexbuffer.begin(7, DefaultVertexFormats.POSITION_TEX_COLOR);
                vertexbuffer.pos((double) k, (double) (i2 + l1 - 1), 0.0D).tex(0.0D, 1.0D).color(192, 192, 192, 255).endVertex();
                vertexbuffer.pos((double) (l - 1), (double) (i2 + l1 - 1), 0.0D).tex(1.0D, 1.0D).color(192, 192, 192, 255).endVertex();
                vertexbuffer.pos((double) (l - 1), (double) i2, 0.0D).tex(1.0D, 0.0D).color(192, 192, 192, 255).endVertex();
                vertexbuffer.pos((double) k, (double) i2, 0.0D).tex(0.0D, 0.0D).color(192, 192, 192, 255).endVertex();
                tessellator.draw();
            }

            this.renderDecorations(mouseXIn, mouseYIn);
            GlStateManager.enableTexture2D();
            GlStateManager.shadeModel(7424);
            GlStateManager.enableAlpha();
            GlStateManager.disableBlend();
        }

    }

    public void handleMouseInput() {
        if (this.isMouseInField()) {
            int i;
            int j;
            int k;
            if (Mouse.isButtonDown(0) && this.getEnabled()) {
                if (this.initialClickY != -1.0F) {
                    if (this.initialClickY >= 0.0F) {
                        this.amountScrolled -= ((float) this.mouseY - this.initialClickY) * this.scrollMultiplier;
                        this.initialClickY = (float) this.mouseY;
                    }
                } else {
                    boolean flag = true;
                    if (this.mouseY >= this.top && this.mouseY <= this.bottom) {
                        i = this.width / 2 - this.getListWidth() / 2 + this.left;
                        this.getClass();
                        j = this.width / 2 + this.getListWidth() / 2 + this.left - 6;
                        k = this.mouseY - this.top - this.headerPadding + (int) this.amountScrolled;
                        int l = this.getSlotIndexFromScreenCoords(this.mouseX, this.mouseY);
                        if (this.mouseX >= i && this.mouseX <= j && l >= 0 && k >= 0 && l < this.getSize()) {
                            boolean flag1 = l == this.selectedElement && Minecraft.getSystemTime() - this.lastClicked < 250L;
                            this.elementClicked(l, flag1, this.mouseX, this.mouseY, 0);
                            this.selectedElement = l;
                            this.lastClicked = Minecraft.getSystemTime();
                        } else if (this.mouseX >= i && this.mouseX <= j && k < 0) {
                            this.clickedHeader(this.mouseX - i, this.mouseY - this.top + (int) this.amountScrolled);
                            flag = false;
                        }

                        int i2 = this.getScrollBarX();
                        this.getClass();
                        int i1 = i2 + 6;
                        if (this.mouseX >= i2 && this.mouseX <= i1) {
                            this.scrollMultiplier = -1.0F;
                            int j1 = this.getMaxScroll();
                            if (j1 < 1) {
                                j1 = 1;
                            }

                            int k1 = (this.bottom - this.top) * (this.bottom - this.top) / this.getContentHeight();
                            k1 = MathHelper.clamp(k1, 32, this.bottom - this.top - 8);
                            this.scrollMultiplier = (float) ((double) this.scrollMultiplier / ((double) (this.bottom - this.top - k1) / (double) j1));
                        } else {
                            this.scrollMultiplier = 1.0F;
                        }

                        if (flag) {
                            this.initialClickY = (float) this.mouseY;
                        } else {
                            this.initialClickY = -2.0F;
                        }
                    } else {
                        this.initialClickY = -2.0F;
                    }
                }
            } else {
                this.initialClickY = -1.0F;
            }

            int l1;
            if (Mouse.isButtonDown(1) && this.getEnabled() && this.initialClickY == -1.0F && this.mouseY >= this.top && this.mouseY <= this.bottom) {
                l1 = this.width / 2 - this.getListWidth() / 2 + this.left;
                this.getClass();
                i = this.width / 2 + this.getListWidth() / 2 + this.left - 6;
                j = this.mouseY - this.top - this.headerPadding + (int) this.amountScrolled;
                k = this.getSlotIndexFromScreenCoords(this.mouseX, this.mouseY);
                if (this.mouseX >= l1 && this.mouseX <= i && k >= 0 && j >= 0 && k < this.getSize()) {
                    boolean flag1 = k == this.selectedElement && Minecraft.getSystemTime() - this.lastClicked < 250L;
                    this.elementClicked(k, flag1, this.mouseX, this.mouseY, 1);
                    this.selectedElement = k;
                    this.lastClicked = Minecraft.getSystemTime();
                } else if (this.mouseX >= l1 && this.mouseX <= i && j < 0) {
                    this.clickedHeader(this.mouseX - l1, this.mouseY - this.top + (int) this.amountScrolled);
                }
            }

            l1 = Mouse.getEventDWheel();
            if (l1 != 0) {
                if (l1 > 0) {
                    l1 = -1;
                } else if (l1 < 0) {
                    l1 = 1;
                }

                this.amountScrolled += (float) (l1 * this.getAverageSlotHeight() / 2);
            }
        }

    }

    public boolean getEnabled() {
        return this.enabled;
    }

    public void setEnabled(boolean enabledIn) {
        this.enabled = enabledIn;
    }

    public int getListWidth() {
        return this.width;
    }

    protected void drawSelectionBox(int x, int y, int mouseXIn, int mouseYIn) {
        int i1 = this.getSize();
        Tessellator tessellator = Tessellator.getInstance();
        BufferBuilder vertexbuffer = tessellator.getBuffer();
        int yTotal = y + this.headerPadding;

        for (int index = 0; index < i1; ++index) {
            int slotHeight = this.getSlotHeight(index);
            if (yTotal + slotHeight <= this.bottom && yTotal >= this.top) {
                if (this.showSelectionBox && this.isSelected(index)) {
                    int xLeft = this.left + (this.width / 2 - this.getListWidth() / 2);
                    this.getClass();
                    int xRight = this.left + this.width / 2 + this.getListWidth() / 2 - 6;
                    GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
                    GlStateManager.disableTexture2D();
                    vertexbuffer.begin(7, DefaultVertexFormats.POSITION_TEX_COLOR);
                    vertexbuffer.pos((double) xLeft, (double) (yTotal + slotHeight), 0.0D).tex(0.0D, 1.0D).color(128, 128, 128, 255).endVertex();
                    vertexbuffer.pos((double) xRight, (double) (yTotal + slotHeight), 0.0D).tex(1.0D, 1.0D).color(128, 128, 128, 255).endVertex();
                    vertexbuffer.pos((double) xRight, (double) yTotal, 0.0D).tex(1.0D, 0.0D).color(128, 128, 128, 255).endVertex();
                    vertexbuffer.pos((double) xLeft, (double) yTotal, 0.0D).tex(0.0D, 0.0D).color(128, 128, 128, 255).endVertex();
                    vertexbuffer.pos((double) (xLeft + 1), (double) (yTotal + slotHeight - 1), 0.0D).tex(0.0D, 1.0D).color(0, 0, 0, 255).endVertex();
                    vertexbuffer.pos((double) (xRight - 1), (double) (yTotal + slotHeight - 1), 0.0D).tex(1.0D, 1.0D).color(0, 0, 0, 255).endVertex();
                    vertexbuffer.pos((double) (xRight - 1), (double) (yTotal + 1), 0.0D).tex(1.0D, 0.0D).color(0, 0, 0, 255).endVertex();
                    vertexbuffer.pos((double) (xLeft + 1), (double) (yTotal + 1), 0.0D).tex(0.0D, 0.0D).color(0, 0, 0, 255).endVertex();
                    tessellator.draw();
                    GlStateManager.enableTexture2D();
                }

                this.drawSlot(index, x + 4, yTotal + this.spacingY, slotHeight, mouseXIn, mouseYIn);
                yTotal += slotHeight;
            } else {
                this.slotOutOfBounds(index, x, yTotal);
                yTotal += slotHeight;
            }
        }

    }

    protected int getScrollBarX() {
        this.getClass();
        return this.left + this.width - 6;
    }

    public void setSlotXBoundsFromLeft(int leftIn) {
        this.left = leftIn;
        this.right = leftIn + this.width;
    }

    public int getAverageSlotHeight() {
        int height = 0;
        int biggest = 0;

        for (int index = 0; index < this.getSize(); ++index) {
            int slotheight = this.getSlotHeight(index);
            height += slotheight;
            biggest = biggest < slotheight ? slotheight : biggest;
        }

        return height > 0 ? height / this.getSize() : 9;
    }

    protected void drawContainerBackground(Tessellator tessellator) {
        Gui.drawRect(this.left, this.top, this.right, this.bottom, Integer.MIN_VALUE);
    }
}
